﻿using System.Threading.Channels;

namespace ChannelDemo
{
    class Message
    {
        public int id { get; set; }
        public string msg { get; set; }
    }
    internal class Program
    {
        static Channel<Message> channel;
        static async Task Main(string[] args)
        {
            channel = Channel.CreateUnbounded<Message>();
            var send = SendAsync(channel.Writer, 1);
            var send1 = SendAsync(channel.Writer, 2);
            var receive = Receive(channel.Reader, 3);
            await send;
            await send1;
            channel.Writer.Complete();
            await receive;
            Console.ReadLine();
        }

        static async Task SendAsync(ChannelWriter<Message> write, int id)
        {
            for (int i = 0; i <= 20; i++)
            {
                await write.WriteAsync(new Message() { id = id, msg = $"Message {i}" });
                Console.WriteLine($"Thread {id} sent {i}");
                await Task.Delay(100);
            }
        }
        static async Task Receive(ChannelReader<Message> read, int id)
        {

            try
            {
                //while (!read.Completion.IsCompleted)
                //{
                //    var me = await read.ReadAsync();
                //    Console.WriteLine($"Thread {id} Received {me.msg} from {me.id}");
                //}

                await foreach (var me in read.ReadAllAsync())
                {
                    Console.WriteLine($"Thread {id} Received {me.msg} from {me.id}");
                }
            }
            catch (ChannelClosedException)
            {
                Console.WriteLine($"Thread {id} ChannelCancel");
            }
        }
    }
}